#!/bin/sh /etc/rc.common

USE_PROCD=1
# after network
START=21

my_extra_command() {
	local cmd="$1"
	local help="$2"

	local extra="$(printf "%-16s%s" "${cmd}" "${help}")"
	EXTRA_HELP="${EXTRA_HELP}	${extra}
"
	EXTRA_COMMANDS="${EXTRA_COMMANDS} ${cmd}"
}
my_extra_command stop_fw "Stop zapret firewall (noop in iptables+fw3 case)"
my_extra_command start_fw "Start zapret firewall (noop in iptables+fw3 case)"
my_extra_command restart_fw "Restart zapret firewall (noop in iptables+fw3 case)"
my_extra_command reload_ifsets "Reload interface lists (nftables only)"
my_extra_command list_ifsets "Display interface lists (nftables only)"
my_extra_command list_table "Display zapret nftable (nftables only)"
my_extra_command stop_daemons "Stop zapret daemons only (=stop in iptables+fw3 case)"
my_extra_command start_daemons "Start zapret daemons only (=start in iptables+fw3 case)"
my_extra_command restart_daemons "Restart zapret firewall only (=restart in iptables+fw3 case)"

SCRIPT=$(readlink /etc/init.d/zapret)
if [ -n "$SCRIPT" ]; then
 EXEDIR=$(dirname "$SCRIPT")
 ZAPRET_BASE=$(readlink -f "$EXEDIR/../..")
else
 ZAPRET_BASE=/opt/zapret
fi

. "$ZAPRET_BASE/init.d/openwrt/functions"


# !!!!! in old openwrt 21.x- with iptables firewall rules are configured separately
# !!!!! in new openwrt >21.x with nftables firewall is configured here

PIDDIR=/var/run

[ -n "$NFQWS" ] || NFQWS="$ZAPRET_BASE/nfq/nfqws"
NFQWS_OPT_BASE="--user=$WS_USER --dpi-desync-fwmark=$DESYNC_MARK"

[ -n "$TPWS" ] || TPWS="$ZAPRET_BASE/tpws/tpws"
TPWS_OPT_BASE="--user=$WS_USER"
TPWS_OPT_BASE4="--bind-addr=$TPWS_LOCALHOST4"
TPWS_OPT_BASE6="--bind-addr=::1"
TPWS_WAIT="--bind-wait-ifup=30 --bind-wait-ip=30"
TPWS_WAIT_SOCKS6="$TPWS_WAIT --bind-wait-ip-linklocal=30"
TPWS_OPT_BASE6_PRE="--bind-linklocal=prefer $TPWS_WAIT --bind-wait-ip-linklocal=3"

run_daemon()
{
	# $1 - daemon string id or number. can use 1,2,3,...
	# $2 - daemon
	# $3 - daemon args
	# use $PIDDIR/$DAEMONBASE$1.pid as pidfile
	local DAEMONBASE="$(basename "$2")"
	echo "Starting daemon $1: $2 $3"
	procd_open_instance
	procd_set_param command $2 $3
	procd_set_param pidfile $PIDDIR/$DAEMONBASE$1.pid
	procd_close_instance
}

run_tpws()
{
	[ "$DISABLE_IPV4" = "1" ] && [ "$DISABLE_IPV6" = "1" ] && return 0

	local OPT="$TPWS_OPT_BASE"
	local DEVICE

	[ "$DISABLE_IPV4" = "1" ] || OPT="$OPT $TPWS_OPT_BASE4"
	[ "$DISABLE_IPV6" = "1" ] || {
		OPT="$OPT $TPWS_OPT_BASE6"
		for lan in $OPENWRT_LAN; do
		    network_get_device DEVICE $lan
		    [ -n "$DEVICE" ] && OPT="$OPT --bind-iface6=$DEVICE $TPWS_OPT_BASE6_PRE"
		done
	}
	run_daemon $1 "$TPWS" "$OPT $2"
}
do_tpws()
{
	[ "$1" = 0 ] || { shift; run_tpws "$@"; }
}
run_tpws_socks()
{
	[ "$DISABLE_IPV4" = "1" ] && [ "$DISABLE_IPV6" = "1" ] && return 0

	local opt="$TPWS_OPT_BASE --socks"

	tpws_apply_socks_binds opt
	run_daemon $1 "$TPWS" "$opt $2"
}
do_tpws_socks()
{
	[ "$1" = 0 ] || { shift; run_tpws_socks "$@"; }
}
tpws_apply_socks_binds()
{
	local o

	[ "$DISABLE_IPV4" = "1" ] || o="--bind-addr=127.0.0.1"
	[ "$DISABLE_IPV6" = "1" ] || o="$o --bind-addr=::1"
	
	for lan in $OPENWRT_LAN; do
		network_get_device DEVICE $lan
		[ -n "$DEVICE" ] || continue
		[ "$DISABLE_IPV4" = "1" ] || o="$o --bind-iface4=$DEVICE $TPWS_WAIT"
		[ "$DISABLE_IPV6" = "1" ] || o="$o --bind-iface6=$DEVICE --bind-linklocal=unwanted $TPWS_WAIT_SOCKS6"
	done
	eval $1="\"\$$1 $o\""
}

run_nfqws()
{
	run_daemon $1 "$NFQWS" "$NFQWS_OPT_BASE $2"
}
do_nfqws()
{
	[ "$1" = 0 ] || { shift; run_nfqws "$@"; }
}

start_daemons_procd()
{
	standard_mode_daemons 1
	custom_runner zapret_custom_daemons 1

	return 0
}
start_daemons()
{
	rc_procd start_daemons_procd "$@"
}
stop_daemons()
{
	local svc="$(basename ${basescript:-$initscript})"
	procd_running "$svc" "$1" && procd_kill "$svc" "$1"
}
restart_daemons()
{
	stop_daemons
	start_daemons
}

start_fw()
{
	zapret_apply_firewall
}
stop_fw()
{
	zapret_unapply_firewall
}
restart_fw()
{
	stop_fw
	start_fw
}
reload_ifsets()
{
	zapret_reload_ifsets
}
list_ifsets()
{
	zapret_list_ifsets
}
list_table()
{
	zapret_list_table
}

start_service()
{
	start_daemons_procd
	[ "$INIT_APPLY_FW" != "1" ] || {
		linux_fwtype
		openwrt_fw3_integration || start_fw
	}
}

stop_service()
{
	# this procedure is called from stop()
	# stop() already stop daemons
	[ "$INIT_APPLY_FW" != "1" ] || {
		linux_fwtype
		openwrt_fw3_integration || stop_fw
	}
}
